﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[ExecuteInEditMode]
public class HCHexagonController : MonoBehaviour {
	
	public enum EType
	{
		EMPTY = 0,
		BLACK,
		WHITE,
		SOLID,
		WILDCARD
	}
	
	float _alpha = 0.8f;
	
	[SerializeField]
	private HCHexagon _view = null;
	
	[SerializeField]
	private HCGrid _grid = null; 
	
	[SerializeField]
	private int _row = -1;
	
	[SerializeField]
	private int _column = -1;
	
	[SerializeField]
	private EType _type = EType.EMPTY;
	
	[SerializeField]
	private float _energy = 100f;
	
	[SerializeField]
	private float _currentTypePercent = 1f;
	
	[SerializeField]
	private Unit _unit = null;
	
	[SerializeField]
	private ArrayList _neighborhood = null;

	EType _lastHitBy = EType.EMPTY;

	public HCHexagon View
	{
		get{ return _view; }
		set{ _view = value; }
	}
	
	// properties
	public HCGrid Grid
	{
		get{ return _grid; }
		set{ _grid = value; }
	}
	
	public int Row
	{
		get{ return _row; }
		set{ _row = value; }
	}
	
	public int Column
	{
		get{ return _column; } 	
		set{ _column = value; }
	}
	
	public Unit Unit
	{
		get { return _unit; }
		set 
		{ 
			if( _unit )
				_unit.EventHandler.RemoveEventListener<float, EType >("OnHit", UnitHit);
			
			_unit = value; 
			
			if( null != _unit )
			{
				_unit.Hexagon = this;
				_unit.EventHandler.AddEventListener<float, EType>("OnHit", UnitHit);
			}
				
				
		}
	}
	
	void SetAlpha()
	{
		if( null != _view )
		{
			/*
			Color _current = _view.renderer.material.color;			
			_current.a = (_energy / 100f) * _alpha;
			_view.renderer.material.color = _current;	
			*/
			
			_view.renderer.material.SetFloat("_Cutoff", _energy / 100f * _alpha );
		}
	}
	
	void Awake()
	{		
		//SetAlpha();
	}
	
	public EType Type
	{
		get{ return this._type; }
		set{ this._type = value; }
	}
	
	public ArrayList Neighborhood
	{
		get { return this._neighborhood; }
		set { this._neighborhood = value; }
	}
	
	public void UnitHit(float _damage, EType _fromType)
	{
		// derivar golpe a unidad o a cambio de control
		//Debug.Log ("hit: " + _damage.ToString() );
		// derivamos el golpe a los demas vecinos
		if( null != _neighborhood )
		{
			// golpear a cada celda que no es de mi faccion
			int _count = 0;
			List<HCHexagonController> _listToHit = new List<HCHexagonController>();
			foreach( HCHexagonController _hc in _neighborhood )
			{
				// si el vecino no es de mi faccion
				if( _hc._type != _type || _hc._energy < 100f )
					//_count++; 
					_listToHit.Add(_hc);
			}
			/*
			if( _count > 0 )
			{
				float _derivedDamage = _damage / _count;
				foreach( HCHexagonController _hc in _neighborhood )
				{
					// si el vecino no es de mi faccion o no tengo la energa al 100%
					if( _hc._type != _type || _hc._energy < 100f )
						_hc.ReduceEnergyBy(_derivedDamage, _fromType );
				}
			}
			*/
			_count = _listToHit.Count;
			if( _count > 0 )
			{
				float _derivedDamage = _damage / _count;
				foreach( HCHexagonController _hc in _listToHit )
				{
					_hc.ReduceEnergyBy( _derivedDamage, _fromType );
				}
			}
		}
	}

	public void ReduceEnergyBy(float _value, EType _fromType )
	{
		// si hay una unidad bajarle la energia
		if (null != this.Unit && Unit.Faction != _fromType) 
		{
			Unit.ApplyDamage (_value);
		} else {
			
			if( _fromType != _type )
			{
				_energy -= _value;
			}else if( _energy < 100f ){
				_energy += _value;
			}
			
			if( _energy < 0f )
			{
				_energy = 0f;
				_type = _fromType;				
				_view.renderer.material = _grid.GetMaterialByType( _type );
			}
			else if( _energy > 100f )
			{
				_energy = 100f;
			}
			
			SetAlpha();
			
		}
	}

	public bool Swap( HCHexagonController _hex )
	{
			
		// primero vemos si es de la misma faccion
		if( Type != _hex.Type )
			return false;
		
		ArrayList _nearHex = _grid.GetNearHexagon(_hex);
		
		bool _find = false;
		foreach( HCHexagonController h in _nearHex )
		{
			if( h.Equals(this) )
			{
				_find = true;
				break;
			}
		}
		
		if( !_find )return false;
		
		// move the previosly selected hex unit
		
		if( _hex.Unit.canMove )
		{
			// move the unit to the position
			if( null != _unit )
			{
				if( !_unit.canMove )
					return false;
				Unit.MoveTo( _hex.View.transform.position );		
			}
			
			_hex.Unit.MoveTo( View.transform.position );
					
			
			// change the units
			Unit _auxUnit = this.Unit;
			this.Unit = _hex.Unit;
			_hex.Unit = _auxUnit;
			
			return true;
		}
		
		return false;
	}
		
	/**
	* Ejecuta el seleccionador del hexagono en cuestion
	*/
	public bool Select()
	{
		// solo si tiene una unidad añadida
		if( null != _unit )
		{
			return true;
		}
		return false;
	}
	
	void Start()
	{
		
	}
	
	void Update()
	{
		// si tiene unit 
		if( null != _unit )
		{
			//ArrayList _list = _grid.GetNearHexagon( this );
		}
	}
	
	
	
}
